package com.wclass.controller.app;


import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.google.common.collect.Lists;
import com.wclass.common.CarNumberUtil;
import com.wclass.common.DateUtil;
import com.wclass.common.ReturnObject;
import com.wclass.entity.*;
import com.wclass.interceptor.BaseContextHandler;
import com.wclass.interceptor.IgnoreAuth;
import com.wclass.service.*;
import io.rong.RongCloud;
import io.rong.models.group.GroupMember;
import io.rong.models.group.GroupModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Base64;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 课程订单 前端控制器
 * </p>
 *
 * @author 张浩高
 * @since 2018-12-21
 */
@RestController
@Api(description = "课程订单")
@RequestMapping("/couresOrder")
public class CouresOrderController {
    /**
     * 融云
     */
    @Value("${rong.appKey}")
    private String appKey;
    /**
     * 融云
     */
    @Value("${rong.appSecret}")
    private String appSecret;

    @Autowired
    private ICouresOrderService iCouresOrderService;
    @Autowired
    private ICourseInfoService iCourseInfoService;
    @Autowired
    private IBaseAppUserService iBaseAppUserService;
    @Autowired
    private IBaseFeedbackService iBaseFeedbackService;
    @Autowired
    private IUserSettlementService iUserSettlementService;
    @Autowired
    private IBaseOrganService iBaseOrganService;

    @ApiOperation("获取订单分页")
    @RequestMapping(value = "/getPage", method = RequestMethod.POST)
    public ReturnObject<List<CouresOrder>> getPage(@ApiParam("每页条数") @RequestParam(defaultValue = "10") int limit,
                                                   @ApiParam("页数") @RequestParam(defaultValue = "1") int offset,
                                                   @ApiParam("支付状态(0：等待支付，1：支付成功，2：退款中，3：已退款，4：交易关闭)") Integer payState) {
        EntityWrapper<CouresOrder> ew = new EntityWrapper<>();
        ew.orderBy("info.crt_time", false);
        ew.eq("info.pay_person_id", BaseContextHandler.getUserID());
        if (payState != null)
            ew.eq("info.pay_state", payState);
        Page<CouresOrder> obj = iCouresOrderService.selectPage(new Page<>(offset, limit), ew);
        return new ReturnObject<>(0, "获取成功", obj.getTotal(), obj.getPages(), obj.getRecords());
    }

    @ApiOperation("订单详情")
    @RequestMapping(value = "/info", method = RequestMethod.POST)
    public ReturnObject<CouresOrder> info(@ApiParam("订单id") @RequestParam Long id) {
        return new ReturnObject<>(0, "获取成功", iCouresOrderService.selectById(id));
    }

    @IgnoreAuth
    @ApiOperation("获取课程评价分页")
    @RequestMapping(value = "/getEvaluatePage", method = RequestMethod.POST)
    public ReturnObject<List<CouresOrder>> getEvaluatePage(@ApiParam("每页条数") @RequestParam(defaultValue = "10") int limit,
                                                           @ApiParam("页数") @RequestParam(defaultValue = "1") int offset,
                                                           @ApiParam("课程id") @RequestParam Long couresId,
                                                           @ApiParam("评分筛选，1：好评，2：中评，3、差评") @RequestParam(defaultValue = "0") Integer type) throws Exception {
        EntityWrapper<CouresOrder> ew = new EntityWrapper<>();
        ew.eq("info.course_info_id", couresId);
        ew.orderBy("info.crt_time", false);
        ew.eq("info.pay_state", 1);
        ew.isNotNull("info.score");
        if (type == 1) {
            ew.ge("info.score", 5);
        } else if (type == 2) {
            ew.ge("info.score", 3).lt("info.score", 5);
        } else if (type == 3) {
            ew.ge("info.score", 0).lt("info.score", 3);
        }
        Page<CouresOrder> obj = iCouresOrderService.selectPage(new Page<>(offset, limit), ew);

        for (CouresOrder couresOrder : obj.getRecords()) {
            //进行解码
            couresOrder.setEvaluate(new String(Base64.getDecoder().decode(couresOrder.getEvaluate().getBytes()),"utf-8"));
        }

        return new ReturnObject<>(0, "获取成功", obj.getTotal(), obj.getPages(), obj.getRecords());
    }

    @ApiOperation("课程下订单-新增")
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public ReturnObject<CouresOrder> add(@ApiParam("课程id") @RequestParam Long couresId,
                                         @ApiParam("支付平台(0:安卓，1:ios,2:web)") @RequestParam Integer payTerrace,
                                         @ApiParam("支付方式(0:支付宝，1:微信支付)") @RequestParam Integer payMethod) {
        //查询用户该课程是否已下有效订单
        int count = iCouresOrderService.selectCount(
                new EntityWrapper<CouresOrder>().eq("pay_person_id", BaseContextHandler.getUserID())
                        .eq("course_info_id", couresId).notIn("pay_state", "3,4"));
        if (count > 0)
            return new ReturnObject<>(-1, "课程已下单，不能重复购买");

        CourseInfo courseInfo = iCourseInfoService.selectById(couresId);
        CouresOrder couresOrder = new CouresOrder(CarNumberUtil.getOrderNo(), 0, couresId, courseInfo.getUserId(),
                courseInfo.getAmount(), null, courseInfo.getAmount() == 0 ? 1 : 0,
                courseInfo.getAmount() == 0 ? new Date() : null, payTerrace, payMethod, BaseContextHandler.getUserID(), null, null, 0, null, null, null, null, null, null
                , null, null, null, null, 0, 0, 0, BigDecimal.ZERO, BigDecimal.ZERO, null, null);
        iCouresOrderService.insert(couresOrder);

        if (couresOrder.getPayState() == 1) {
            iCouresOrderService.updateStudentNum(courseInfo, couresOrder, BaseContextHandler.getUserID(), 0);
        }

        //默认加入群
        try {
            GroupMember[] members = {new GroupMember().setId(BaseContextHandler.getUserID().toString())};
            GroupModel group = new GroupModel()
                    .setId(courseInfo.getId().toString())
                    .setMembers(members)
                    .setName(courseInfo.getName());
            RongCloud rongCloud = RongCloud.getInstance(appKey, appSecret);
            rongCloud.group.join(group);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return new ReturnObject<>(0, "获取成功", couresOrder);
    }

    /**
     * 支付订单成功,添加待结算数据
     * @return
     */
    public ReturnObject payForOrder(Long couresOrderId){
        CouresOrder couresOrder = iCouresOrderService.selectById(couresOrderId);

        couresOrder.setPayState(1);
        couresOrder.setSettlementState(1);
        //服务费率10%
        couresOrder.setServeMoney(BigDecimal.valueOf(couresOrder.getAmount()).multiply(BigDecimal.valueOf(0.1)).setScale(2));
        iCouresOrderService.updateById(couresOrder);

        //更新机构、教师学生数量
        iCouresOrderService.updateStudentNum(iCourseInfoService.selectById(couresOrder.getCourseInfoId()), couresOrder, BaseContextHandler.getUserID(), 0);

        //待结算数据增加
        String time = DateUtil.format(couresOrder.getCrtTime(), "yyyy-MM");
        UserSettlement userSettlement = iUserSettlementService.selectOne(
                new EntityWrapper<UserSettlement>().eq("user_id", couresOrder.getUserId()).eq("time", time).eq("type", 1));
        if (userSettlement == null) {
            if (userSettlement == null) {
                userSettlement = new UserSettlement();
                userSettlement.setCrtTime(new Date());
                userSettlement.setUserId(couresOrder.getUserId());
                userSettlement.setTime(time);
                userSettlement.setOrderNum(1);
                userSettlement.setMoney(BigDecimal.valueOf(couresOrder.getAmount()).subtract(couresOrder.getServeMoney()));
                userSettlement.setType(1);
                iUserSettlementService.insert(userSettlement);
            }
        } else {
            userSettlement.setOrderNum(userSettlement.getOrderNum() + 1);
            userSettlement.setMoney(userSettlement.getMoney().add(BigDecimal.valueOf(couresOrder.getAmount()).subtract(couresOrder.getServeMoney())));
            iUserSettlementService.updateById(userSettlement);
        }
        return new ReturnObject(0, "支付成功");
    }

    @ApiOperation("课程订单评价-新增")
    @RequestMapping(value = "/addEvaluate", method = RequestMethod.POST)
    public ReturnObject<CouresOrder> addEvaluate(@ApiParam("课程id") @RequestParam Long id,
                                                 @ApiParam("评分") @RequestParam Integer score,
                                                 @ApiParam("评价内容") String evaluate,
                                                 @ApiParam("评价标签（json格式）") String evaluateLabel) throws Exception {
        EntityWrapper<CouresOrder> courseEw = new EntityWrapper<>();
        courseEw.eq("course_info_id", id);
        courseEw.eq("pay_person_id", BaseContextHandler.getUserID());
        CouresOrder couresOrder = iCouresOrderService.selectOne(courseEw);
        if (couresOrder.getPayState() != 1) {
            return new ReturnObject<>(-1, "该订单无法评价");
        }
        long dateDiff = DateUtil.dateDiff(couresOrder.getPayTime(), new Date());
        int minutes = new Long(dateDiff/(1000 * 60)).intValue();
        if (minutes < 20) {
            return new ReturnObject<>(-1, "购买报名后20分钟内订单无法评价");
        }
        if (couresOrder.getEvaluateState() == 1) {
            return new ReturnObject<>(-1, "该订单已评价，请不要重复评价");
        }
        //进行编码
        evaluate = new String(Base64.getEncoder().encode(evaluate.getBytes()));
        couresOrder.setScore(score);
        couresOrder.setEvaluate(evaluate);
        couresOrder.setEvaluateState(1);
        couresOrder.setEvaluateLabel(evaluateLabel);
        couresOrder.setEvaluateTime(new Date());
        iCouresOrderService.updateById(couresOrder);

        //更新老师评价标签
        BaseAppUser baseAppUser = iBaseAppUserService.selectById(iCourseInfoService.selectById(couresOrder.getCourseInfoId()).getUserId());
        List<String> list;
        if (StringUtils.isNotBlank(baseAppUser.getEvaluateLabel())) {
            list = JSONArray.parseArray(baseAppUser.getEvaluateLabel(), String.class);
            list.removeAll(JSONArray.parseArray(evaluateLabel, String.class));
        } else {
            list = Lists.newArrayList();
        }

        list.addAll(JSONArray.parseArray(evaluateLabel, String.class));
        BaseAppUser newUser = new BaseAppUser();
        newUser.setId(baseAppUser.getId());
        newUser.setEvaluateLabel(JSONArray.toJSONString(list));
        iBaseAppUserService.updateById(newUser);
        //更新课程的评价标签
        CourseInfo courseInfo = iCourseInfoService.selectById(couresOrder.getCourseInfoId());
        if (StringUtils.isNotBlank(courseInfo.getEvaluateLabel())) {
            list = JSONArray.parseArray(courseInfo.getEvaluateLabel(), String.class);
            list.removeAll(JSONArray.parseArray(evaluateLabel, String.class));
        } else {
            list = Lists.newArrayList();
        }
        //更新课程评分
        Object avgScoreObj = iCouresOrderService.selectObj(new EntityWrapper<CouresOrder>().eq("course_info_id",
                couresOrder.getCourseInfoId()).eq("pay_state", 1).isNotNull("score").setSqlSelect("AVG(score)"));
        BigDecimal avgScore = new BigDecimal(avgScoreObj.toString());
        courseInfo.setStar(avgScore.doubleValue());
        list.addAll(JSONArray.parseArray(evaluateLabel, String.class));
        courseInfo.setEvaluateLabel(JSONArray.toJSONString(list));
        courseInfo.setEvaluateNum(iCouresOrderService.selectCount(new EntityWrapper<CouresOrder>().eq("course_info_id"
                , couresOrder.getCourseInfoId()).eq("pay_state", 1).isNotNull("score")));
        courseInfo.setFeedbackRate(iCouresOrderService.selectCount(new EntityWrapper<CouresOrder>().eq("course_info_id"
                , couresOrder.getCourseInfoId()).eq("pay_state", 1).ge("score", 4)) * 100 / courseInfo.getEvaluateNum());
        iCourseInfoService.updateById(courseInfo);
        return new ReturnObject<>(0, "获取成功", couresOrder);
    }

    @ApiOperation("学生订单-申请退款")
    @RequestMapping(value = "/applyRefund", method = RequestMethod.POST)
    public ReturnObject applyRefund(@ApiParam("课程订单id") @RequestParam Long id) {
        CouresOrder couresOrder = iCouresOrderService.selectById(id);
        if (couresOrder == null)
            return new ReturnObject<>(-1, "课程订单id不能为空");
        if (couresOrder.getPayState() != 1)
            return new ReturnObject<>(-1, "课程订单状态不能申请退款");

        //订单支付状态修改
        couresOrder.setPayState(2);
        iCouresOrderService.updateById(couresOrder);

        return new ReturnObject<>(0, "申请成功");
    }

    @ApiOperation("教师评论管理-订单评价-列表")
    @RequestMapping(value = "/getTeaEvaluatePage", method = RequestMethod.POST)
    public ReturnObject<List<CouresOrder>> getTeaEvaluatePage(@ApiParam("每页条数") @RequestParam(defaultValue = "10") Integer limit,
                                                              @ApiParam("页数") @RequestParam(defaultValue = "1") Integer offset,
                                                              @ApiParam("评分类型（0：全部，1：好评，2：中评，3：差评）") @RequestParam Integer scoreType,
                                                              @ApiParam("教师id") @RequestParam Long userId,
                                                              @ApiParam("课程id") Long courseId) throws Exception {
        EntityWrapper<CouresOrder> ew = new EntityWrapper<>();
        ew.setSqlSelect(",courseInfo.star as course_star");
        if (courseId != null)
            ew.eq("info.course_info_id", courseId);
        //好评分数>=5，3<=中评分数<5，1<=差评分数<3
        if (scoreType == 1)
            ew.ge("info.score", 5);
        else if (scoreType == 2)
            ew.ge("info.score", 3).lt("info.score", 5);
        else if (scoreType == 3)
            ew.lt("info.score", 3);
        ew.isNotNull("info.score");
        ew.eq("info.user_id", userId);
        ew.orderBy("info.evaluate_time", false);
        ew.eq("info.pay_state", 1);
        Page<CouresOrder> obj = iCouresOrderService.selectPage(new Page<>(offset, limit), ew);

        for (CouresOrder couresOrder : obj.getRecords()) {
            //进行解码
            couresOrder.setEvaluate(new String(Base64.getDecoder().decode(couresOrder.getEvaluate().getBytes()),"utf-8"));
        }

        return new ReturnObject<>(0, "获取成功", obj.getTotal(), obj.getPages(), obj.getRecords());
    }

    @ApiOperation("教师评论管理-申诉")
    @RequestMapping(value = "/addEvaluateFeedback", method = RequestMethod.POST)
    public ReturnObject addEvaluateFeedback(@ApiParam("课程订单id") @RequestParam Long id,
                                            @ApiParam("申诉理由") @RequestParam String content) {
        CouresOrder couresOrder = iCouresOrderService.selectById(id);

        //插入申诉记录
        BaseFeedback feedback = new BaseFeedback();
        feedback.setCrtTime(new Date());
        feedback.setState(0);
        feedback.setContent(content);
        feedback.setType(1);
        feedback.setCourseOrderId(id);
        feedback.setUserId(BaseContextHandler.getUserID());
        iBaseFeedbackService.insert(feedback);
        //订单申诉状态修改
        couresOrder.setFeedbackState(1);
        iCouresOrderService.updateById(couresOrder);

        return new ReturnObject<>(0, "申诉成功");
    }

    @ApiOperation("教师端--获取订单分页")
    @RequestMapping(value = "/getTeaPage", method = RequestMethod.POST)
    public ReturnObject<List<CouresOrder>> getTeaPage(@ApiParam("每页条数") @RequestParam(defaultValue = "10") int limit,
                                                      @ApiParam("页数") @RequestParam(defaultValue = "1") int offset,
                                                      @ApiParam("支付状态(0：等待支付，1：支付成功，2：退款中，3：已退款，4：交易关闭)") Integer payState,
                                                      @ApiParam("课程id") Long couresId,
                                                      @ApiParam("交易开始时间（yyyy-MM-dd）") String startPayTime,
                                                      @ApiParam("交易结束时间（yyyy-MM-dd）") String endPayTime) throws ParseException {
        EntityWrapper<CouresOrder> ew = new EntityWrapper<>();
        ew.orderBy("info.crt_time", false);
        ew.eq("info.user_id", BaseContextHandler.getUserID());
        if (payState != null)
            ew.eq("info.pay_state", payState);
        if (couresId != null)
            ew.eq("info.course_info_id", couresId);
        if (StringUtils.isNotBlank(startPayTime))
            ew.ge("info.order_time", DateUtil.dateParse(startPayTime + " 00:00:00", "yyyy-MM-dd HH:mm:ss"));
        if (StringUtils.isNotBlank(endPayTime))
            ew.le("info.order_time", DateUtil.dateParse(endPayTime + " 23:59:59", "yyyy-MM-dd HH:mm:ss"));
        Page<CouresOrder> obj = iCouresOrderService.selectPage(new Page<>(offset, limit), ew);
        return new ReturnObject<>(0, "获取成功", obj.getTotal(), obj.getPages(), obj.getRecords());
    }

    @ApiOperation("我的订单-删除订单")
    @RequestMapping(value = "/delOrder", method = RequestMethod.POST)
    public ReturnObject delOrder(@ApiParam("课程订单id") @RequestParam Long id) {
        CouresOrder couresOrder = iCouresOrderService.selectById(id);

        //订单删除状态修改
        couresOrder.setState(1);
        iCouresOrderService.updateById(couresOrder);

        return new ReturnObject<>(0, "删除成功");
    }

    @ApiOperation("教师-我的订单-同意退款")
    @RequestMapping(value = "/agreeRefund", method = RequestMethod.POST)
    public ReturnObject agreeRefund(@ApiParam("课程订单id") @RequestParam Long id) {
        CouresOrder couresOrder = iCouresOrderService.selectById(id);

        //订单支付状态修改
        couresOrder.setPayState(3);
        couresOrder.setServeMoney(BigDecimal.ZERO);
        couresOrder.setRefundMoney(BigDecimal.valueOf(couresOrder.getAmount()));
        iCouresOrderService.updateById(couresOrder);

        //更新机构、教师学生数量
        iCouresOrderService.updateStudentNum(iCourseInfoService.selectById(couresOrder.getCourseInfoId()), couresOrder, BaseContextHandler.getUserID(), 1);

        //待结算数据减少
        String time = DateUtil.format(couresOrder.getCrtTime(), "yyyy-MM");
        UserSettlement userSettlement = iUserSettlementService.selectOne(
                new EntityWrapper<UserSettlement>().eq("user_id", couresOrder.getUserId()).eq("time", time).eq("type", 1));

        userSettlement.setOrderNum(userSettlement.getOrderNum() + 1);
        userSettlement.setMoney(userSettlement.getMoney().subtract(couresOrder.getRefundMoney()));
        iUserSettlementService.updateById(userSettlement);


        return new ReturnObject<>(0, "退款成功");
    }

}

